﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Firestarter.DB.Schema.BO;
using Habanero.Util;

namespace FireStarterModeller.BO
{
    public static class IntegrationExtentionMethods
    {

        public static void SetMappedDMProperty(this DBColumn column, IDMProperty value)
        {
            if (column == null) return;
            column.Relationships.SetRelatedObject("MappedDMProperty", value);
        }

        public static DMProperty FindBOProperty(this IDBColumn column, DMClass dmClass)
        {
            if (column == null) return null;
            DMProperty foundProp = column.GetMappedDMProperty();
            if (foundProp == null)
            {
                foundProp = dmClass.FindBOPropertyByColumnId(column.ColumnID);
            }
            if (column.ColumnName == null) return null;
            if (foundProp == null)
            {
                foundProp = dmClass.FindBOPropertyByColumnName(column.ColumnName);
            }
            if (foundProp == null)
            {
                foundProp = dmClass.FindPropByName(PascalCaseFieldName(column.ColumnName));
            }
            return foundProp;
        }


        private static string PascalCaseFieldName(string fieldName)
        {
            if (fieldName == null) return "";
            return StringUtilities.PascalCaseTableName(fieldName.Trim());
        }
        public static DMProperty GetMappedDMProperty(this IDBColumn column)
        {
            var dbColumn =column as  DBColumn;
            if (dbColumn != null)
            {
                return dbColumn.Relationships.GetRelatedObject<DMProperty>("MappedDMProperty");
            }
            var dbViewColumn = column as DBViewColumn;
            if (dbViewColumn != null)
            {
                return dbViewColumn.Relationships.GetRelatedObject<DMProperty>("MappedDMProperty");
            }

            return null;
        }

        public static string GetMappedPropertyName(this DBColumn column)
        {
            if (column == null) return "";
            return column.GetMappedDMProperty() == null ? "" : column.GetMappedDMProperty().PropertyName;
        }
        /// <summary>
        /// The <see cref="DMClass"/> for this Foreign Key via its <see cref="DBForeignKey.ParentTable"/>
        /// </summary>
        public static IDMClass ParentDMClass(this DBForeignKey foreignKey)
        {
            if (foreignKey == null) return null;
            return foreignKey.ParentTable == null ? null : foreignKey.ParentTable.GetMappedDMClass(); 
        }
        /// <summary>
        /// The <see cref="DMClass"/> for this Foreign Key via its <see cref="DBForeignKey.RelatedTable"/>
        /// </summary>
        public static IDMClass RelatedDMClass(this DBForeignKey foreignKey)
        {
            if (foreignKey == null) return null;
            return foreignKey.RelatedTable == null ? null : foreignKey.RelatedTable.GetMappedDMClass(); 
        }

        public static void SetSolution(this ReverseEngineering revEng, DMSolution value)
        {
            if (revEng == null) return;
            revEng.Relationships.SetRelatedObject("Solution", value);
        }

        public static DMSolution GetSolution(this IReverseEngineering revEng)
        {
            if (revEng == null) return null;
            return revEng.Relationships.GetRelatedObject<DMSolution>("Solution");
        }

        public static void SetMappedDMClass(this DBTable table, DMClass value)
        {
            if (table == null) return;
            table.Relationships.SetRelatedObject("MappedDMClass", value);
        }

        public static DMClass GetMappedDMClass(this IDBTable table)
        {
            DBTable dbTable = table as DBTable;
            if (dbTable != null)
            {

                return dbTable.Relationships.GetRelatedObject<DMClass>("MappedDMClass");
            }
            DBView dbView = table as DBView;
            if (dbView != null)
            {

                return dbView.Relationships.GetRelatedObject<DMClass>("MappedDMClass");
            }
            return null;
        }
        public static void SetMappedDMObjectIdentity(this DBPrimaryKey pk, DMObjectIdentity value)
        {
            if (pk == null) return ;
            pk.Relationships.SetRelatedObject("MappedDMObjectIdentity", value);
        }

        public static DMObjectIdentity GetMappedDMObjectIdentity(this DBPrimaryKey pk)
        {
            if (pk == null) return null;
            return pk.Relationships.GetRelatedObject<DMObjectIdentity>("MappedDMObjectIdentity");
        }

        public static string GetParentPropertyName(this DBForeignKeyColumn fkColumn)
        {
            if (fkColumn == null) return "";
            return fkColumn.ParentColumn == null ? "" : fkColumn.ParentColumn.GetMappedPropertyName();
        }

        public static string GetPropertyName(this DBKeyColumn keyColumn)
        {
            if (keyColumn == null) return "";
            return keyColumn.Column == null ? "" : keyColumn.Column.GetMappedPropertyName();
        }

        public static string GetRelatedPropertyName(this DBForeignKeyColumn fkColumn)
        {
            if (fkColumn == null) return "";
            return fkColumn.RelatedColumn == null ? "" : fkColumn.RelatedColumn.GetMappedPropertyName();
        }
        public static void SetMappedDMRelationship(this DBForeignKey foreignKey, DMRelationship value)
        {
            if (foreignKey == null) return;
            foreignKey.Relationships.SetRelatedObject("MappedDMRelationship", value);
        }
        
        public static DMRelationship GetMappedDMRelationship(this DBForeignKey foreignKey)
        {
            if (foreignKey == null || foreignKey.Relationships == null) return null;
            return foreignKey.Relationships.GetRelatedObject<DMRelationship>("MappedDMRelationship");
        }

/*        public static DMProperty FindBOProperty(this DBColumn column, DMClass dmClass)
        {
            DMProperty foundProp = column.GetMappedDMProperty();
            if (foundProp == null)
            {
                foundProp = dmClass.FindBOPropertyByColumnId(column.ColumnID);
            }
            if (foundProp == null)
            {
                foundProp = dmClass.FindBOPropertyByColumnName(column.ColumnName);
            }
            if (foundProp == null)
            {
                foundProp = dmClass.FindPropByName(PascalCaseFieldName(column.ColumnName));
            }
            return foundProp;
        }*/
        public static DMRelationship FindMappedDMRelationship(this DBForeignKey foreignKey, DMClass dmClass)
        {
            if (foreignKey == null) return null;
            DMRelationship relationship = foreignKey.GetMappedDMRelationship();
            if(relationship == null)
            {
                relationship =
                    dmClass.OwnerRelationships.FirstOrDefault(
                        dmRelationship => dmRelationship.RelationshipName == foreignKey.ForeignKeyName);
            }
            
            return relationship;
        }
        public static DMUniqueConstraint GetMappedDMUniqueConstraint(this DBKey key)
        {
            if (key == null) return null;
            return key.Relationships.GetRelatedObject<DMUniqueConstraint>("MappedDMUniqueConstraint");
        }

        public static void SetMappedDMUniqueConstraint(this DBKey key, DMUniqueConstraint value)
        {
            if (key == null) return;
            key.Relationships.SetRelatedObject("MappedDMUniqueConstraint", value);
        }
    }
}
